using Google.Protobuf;
using System.Reflection;
using muduoDotNet;

namespace muduoDotNet.Examples.ReflectionProtocol
{
    /// <summary>
    /// 基础消息处理器类
    /// 利用反射特性自动注册和处理协议消息
    /// </summary>
    public abstract class BaseMessageHandler
    {
        private readonly Dictionary<Type, MethodInfo> _messageHandlers;

        protected BaseMessageHandler()
        {
            _messageHandlers = new Dictionary<Type, MethodInfo>();
            RegisterMessageHandlers();
        }

        /// <summary>
        /// 注册所有消息处理方法
        /// 使用反射自动查找所有符合约定的方法
        /// </summary>
        private void RegisterMessageHandlers()
        {
            var type = GetType();
            var methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            foreach (var method in methods)
            {
                // 检查方法是否符合消息处理器的约定
                // 约定: 方法名为Handle+消息类型名，参数为(TcpConnection connection, T message)
                var parameters = method.GetParameters();
                if (parameters.Length == 2 &&
                    parameters[0].ParameterType == typeof(TcpConnection) &&
                    typeof(IMessage).IsAssignableFrom(parameters[1].ParameterType) &&
                    method.Name.StartsWith("Handle"))
                {
                    var messageType = parameters[1].ParameterType;
                    _messageHandlers[messageType] = method;
                    Logger.Debug($"Registered message handler: {method.Name} for type {messageType.Name}");
                }
            }
        }

        /// <summary>
        /// 处理接收到的消息
        /// 使用反射调用对应的处理方法
        /// </summary>
        /// <param name="connection">TCP连接</param>
        /// <param name="message">消息对象</param>
        public void HandleMessage(TcpConnection connection, IMessage message)
        {
            try
            {
                var messageType = message.GetType();
                if (_messageHandlers.TryGetValue(messageType, out var method))
                {
                    method.Invoke(this, new object[] { connection, message });
                    Logger.Debug($"Handled message: {messageType.Name}");
                }
                else
                {
                    Logger.Warning($"No handler registered for message type: {messageType.Name}");
                    OnUnhandledMessage(connection, message);
                }
            }
            catch (Exception ex)
            {
                Logger.Error($"Error handling message {message.GetType().Name}", ex);
                OnHandleError(connection, message, ex);
            }
        }

        /// <summary>
        /// 处理未识别的消息
        /// 派生类可以重写此方法进行自定义处理
        /// </summary>
        /// <param name="connection">TCP连接</param>
        /// <param name="message">未识别的消息</param>
        protected virtual void OnUnhandledMessage(TcpConnection connection, IMessage message)
        {
            // 默认实现：发送错误状态消息
            var errorStatus = new muduoDotNet.Messages.StatusMessage
            {
                Type = muduoDotNet.Messages.StatusMessage.Types.StatusType.Error,
                Message = $"Unsupported message type: {message.GetType().Name}",
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            };
            connection.SendProtobufMessage(errorStatus);
        }

        /// <summary>
        /// 处理消息处理过程中的错误
        /// 派生类可以重写此方法进行自定义错误处理
        /// </summary>
        /// <param name="connection">TCP连接</param>
        /// <param name="message">导致错误的消息</param>
        /// <param name="ex">异常信息</param>
        protected virtual void OnHandleError(TcpConnection connection, IMessage message, Exception ex)
        {
            // 默认实现：发送错误状态消息
            var errorStatus = new muduoDotNet.Messages.StatusMessage
            {
                Type = muduoDotNet.Messages.StatusMessage.Types.StatusType.Error,
                Message = $"Error processing {message.GetType().Name}: {ex.Message}",
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            };
            connection.SendProtobufMessage(errorStatus);
        }

        /// <summary>
        /// 获取已注册的消息处理器类型列表
        /// </summary>
        /// <returns>消息类型列表</returns>
        public List<Type> GetRegisteredMessageTypes()
        {
            return new List<Type>(_messageHandlers.Keys);
        }
    }
}